﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace Flagwind.Data
{
	/// <summary>
	/// 实体类序列化器
	/// </summary>
	/// <typeparam name="T"></typeparam>
	public class Serializer<T> where T : EntityBase, new()
	{
		public enum SerializeFormates
		{
			Binary,
			XML,
			Json
		}

		/// <summary>
		/// 二进制序列化一个实体类
		/// </summary>
		/// <param name="entity">实体对象实例</param>
		/// <returns>字节数组</returns>
		public static byte[] BinarySerialize(T entity)
		{
			return Serializer.BinarySerialize(entity);
		}

		/// <summary>
		/// 二进制序列化一个实体类数组
		/// </summary>
		/// <param name="entitys"></param>
		/// <returns></returns>
		public static byte[] BinarySerialize(T[] entitys)
		{
			List<byte[]> list = new List<byte[]>();
			foreach(T entity in entitys)
			{
				list.Add(BinarySerialize(entity));
			}
			MemoryStream ms = new MemoryStream();
			BinaryWriter bw = new BinaryWriter(ms);
			bw.Write(Serializer.ENTITY_ARRAY_FLAG); //写入标记
			foreach(byte[] item in list)
			{
				bw.Write(item);
			}
			bw.Close();
			ms.Close();
			return ms.ToArray();
		}

		/// <summary>
		/// 反序列化一个二进制实体类
		/// </summary>
		/// <param name="buffer">二进制实体类字节流</param>
		/// <returns>实体类</returns>
		public static T BinaryDeserialize(byte[] buffer)
		{
			MemoryStream ms2 = new MemoryStream(buffer);
			BinaryReader br = new BinaryReader(ms2);
			EntityInfo ef = EntityFieldsCache.Item(typeof(T));
			T entity = BinaryDeserializeObjectInner(br, ef);
			br.Close();
			ms2.Close();
			return entity;
		}

		private static T BinaryDeserializeObjectInner(BinaryReader br, EntityInfo ef)
		{
			T entity = new T();
			Serializer.BinaryDeserializeCommon(br, ef, entity);
			return entity;
		}

		/// <summary>
		/// 反序列化一个二进制实体类数组
		/// </summary>
		/// <param name="buffer">二进制字节缓存</param>
		/// <returns>实体类数组</returns>
		public static T[] BinaryDeserializeArray(byte[] buffer)
		{
			MemoryStream ms = new MemoryStream(buffer);
			BinaryReader br = new BinaryReader(ms);
			EntityInfo ef = EntityFieldsCache.Item(typeof(T));
			int flag = br.ReadInt32();
			if(flag != Serializer.ENTITY_ARRAY_FLAG)
			{
				throw new Exception("反序列化错误：不是有效的实体类数组格式！");
			}
			long length = (long)buffer.Length;
			List<T> list = new List<T>();
			while(ms.Position < length)
			{
				T entity = BinaryDeserializeObjectInner(br, ef);
				list.Add(entity);
			}
			return list.ToArray();
		}
	}
}